home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / et / et-2_2.lha / et2.2 / src / Application.C < prev    next >
C/C++ Source or Header  |  1990-12-06  |  10KB  |  500 lines

  1. //$Application,ApplDialog,ApplIntHandler$
  2.  
  3. #include "ET++.h"
  4.  
  5. #include "Storage.h"
  6. #include "ObjList.h"
  7. #include "IdDictionary.h"
  8. #include "WindowSystem.h"
  9. #include "FileDialog.h"
  10. #include "ObjectTable.h"
  11. #include "ClassManager.h"
  12. #include "ClipBoard.h"
  13. #include "ProgEnv.h"
  14. #include "FixedStorage.h"
  15. #include "Buttons.h"
  16. #include "BorderItems.h"
  17.  
  18. extern char **environ;
  19.  
  20. extern bool gInMain;
  21.  
  22. bool        gBatch= TRUE;
  23. Application *gApplication= 0;
  24. ClipBoard   *gClipBoard;
  25. char        *gProgname;
  26. int         gArgc;
  27. char        **gArgv;
  28. bool        gMemStatistics;
  29.  
  30. static int untitledCnt= 0;
  31.  
  32. extern bool forcemono;
  33.  
  34. //---- ApplIntHandler --------------------------------------------------------------
  35.  
  36. class ApplIntHandler : public SysEvtHandler {
  37. public:
  38.     ApplIntHandler() : SysEvtHandler(eSigInterrupt)
  39.     { }
  40.     void Notify(SysEventCodes, int);
  41. };
  42.  
  43. void ApplIntHandler::Notify(SysEventCodes, int)
  44. {
  45.     if (gApplication)
  46.     gApplication->Inspect();
  47. }
  48.  
  49. static void ApplErrorHandler(int level, bool, char *location, char *msg)
  50. {
  51.     gApplication->DoOnError(level, location, msg);
  52.  
  53. //---- initial Application Dialog ----------------------------------------------
  54.  
  55. MetaImpl(ApplDialog, (TP(appl), 0));
  56.  
  57. ApplDialog::ApplDialog(Application *eh, char *title)
  58.                 : Dialog(title, eBWinDefault+eBWinFixed, eh)
  59. {   
  60.     appl= eh; 
  61. }
  62.  
  63. VObject *ApplDialog::DoCreateDialog() 
  64. {
  65.     return appl->DoCreateDialog();
  66. }
  67.  
  68. void ApplDialog::Control(int id, int p, void *d)
  69. {   
  70.     EvtHandler::Control(id, p, d);    
  71. }
  72.  
  73. Point ApplDialog::GetInitialPos()
  74. {
  75.     return gPoint0;
  76.  
  77. //---- Application -------------------------------------------------------------
  78.  
  79.  
  80. AbstractMetaImpl(Application, (T(argc), TP(documents), TP(menu),
  81.             TP(applDialog), T(lastDocPos), TB(printHierarchy),
  82.             TP(version), TVP(argv, argc), TP(mainDocumentType),
  83.             TP(gClassManager), TP(gObservers), TP(gWindow), T(gScreenRect),
  84.             TPP(gEnviron), TB(gDebug), TB(gBatch), TB(inited), 0));
  85.  
  86. Application::Application(int ac, char **av, const char *dt)
  87. {
  88.     gInMain= TRUE;
  89.     documents= 0;
  90.     menu= 0;
  91.     applDialog= 0;
  92.     clipboard= 0;
  93.     inited= FALSE;
  94.     version= "Version 2.3, 12/1/90, \251IFI & UBS-UBILAB";
  95.  
  96.     if (gApplication)
  97.     Error("Application", "only one Application !!");
  98.     else {
  99.     UpdateGlobals();
  100.     ObjectTable::AddRoot(this);
  101.     SetErrorHandler(ApplErrorHandler);
  102.     gArgc= argc= ac;
  103.     gArgv= argv= av;
  104.     gProgname= argv[0];
  105.     printHierarchy= FALSE;
  106.     lastDocPos= Point(150, 100);
  107.     documents= new ObjList;
  108.     applDialog= 0;
  109.     menu= 0;
  110.     mainDocumentType= dt;
  111.     }
  112. }
  113.  
  114. Application::~Application()
  115. {
  116.     SetErrorHandler(DefaultErrorHandler);
  117.     SafeDelete(documents);
  118.     SafeDelete(applDialog);
  119.     SafeDelete(menu);
  120.  
  121.     if (gMemStatistics) {
  122.     PrintStorageStatistics();
  123.     MemPools::PrintStatistics();
  124.     }
  125. }
  126.  
  127. void Application::ApplInit()
  128. {
  129.     if (! inited) {
  130.     ParseCommandLine(argc, argv);
  131.     ETInit();
  132.     if (printHierarchy)
  133.         gClassManager->DisplayOn(cout);
  134.     inited= TRUE;
  135.     }
  136. }
  137.  
  138. EvtHandler *Application::GetNextHandler()
  139. {
  140.     return 0;
  141. }
  142.  
  143. FileDialog *Application::MakeFileDialog()
  144. {
  145.     return new FileDialog;
  146. }
  147.  
  148. void Application::ParseCommandLine(int argc, char **argv)
  149. {
  150.     int n, i= 1;
  151.     
  152.     while (i < argc) {
  153.     if (argv[i][0] == '-') {
  154.         n= DoParseOptions(argv[i], argv[i+1]);
  155.         if (n >= 0)
  156.         i+= n;
  157.         else
  158.         i++;
  159.     } else {
  160.         ETInit();
  161.         OpenDocument(argv[i]);
  162.         i++;
  163.     }
  164.     }
  165. }
  166.  
  167. int Application::DoParseOptions(char *arg0, char *arg1)
  168. {
  169.     int x= lastDocPos.x, y= lastDocPos.y;
  170.     
  171.     if (arg0[1] != 'E')
  172.     return 0;
  173.  
  174.     switch(arg0[2]) {
  175.     case 'd':   // debug
  176.     ::gDebug= !::gDebug;
  177.     return 1;
  178.     case 'b':   // double buffer
  179.     ::gBatch= !::gBatch;
  180.     return 1;
  181.     case 'c':   // toggle color monochrome
  182.     forcemono= TRUE;
  183.     return 1;
  184.     case 'h':   // print hierarchie to cerr
  185.     printHierarchy= !printHierarchy;
  186.     return 1;
  187.     case 'm':
  188.     ::gMemStatistics= !::gMemStatistics;
  189.     return 1;
  190.     case 'e':
  191.     EditSource(TRUE);
  192.     return 1;
  193.     case 'E':
  194.     gProgEnv->Start();
  195.     return 1;
  196.     case 'w':
  197.     SetIgnoreLevel(0);
  198.     return 1;
  199.     case 'i':
  200.     Inspect();
  201.     return 1;
  202.     case 'p':
  203.     sscanf(arg1, "%d,%d", &x, &y);
  204.     lastDocPos= Point(x,y);
  205.     return 2;
  206.     }
  207.     return 0;
  208. }
  209.  
  210. char *Application::ProgramName()
  211. {
  212.     char *p= rindex(gProgname, '/');
  213.     if (p)
  214.     return p+1;
  215.     return gProgname;
  216. }
  217.  
  218. Point Application::GetNewDocumentPos()
  219. {
  220.     Point p= lastDocPos;
  221.     lastDocPos+= Point(40, 30);
  222.     return p;
  223. }
  224.  
  225. void Application::RemoveDocument(Document *dp)
  226. {
  227.     if (documents)
  228.     documents->Remove(dp);
  229.     gSystem->AddCleanupObject(dp);
  230. }
  231.  
  232. Menu *Application::GetMenu()
  233. {
  234.     if (menu == 0)
  235.     menu= new Menu(argv[0]);
  236.     return menu;
  237. }
  238.  
  239. void Application::About()
  240. {
  241.     ShowAlert(eAlertSun, "%s %s", argv[0], version);
  242. }
  243.  
  244. void Application::HandleApplicationCommands(int cmd)
  245. {
  246.     switch(cmd) {
  247.  
  248.     case cNEW:
  249.     NewDocument(mainDocumentType);
  250.     break;
  251.  
  252.     case cQUIT:
  253.     Quit();
  254.     break;
  255.  
  256.     case cABOUT:
  257.     About();
  258.     break;
  259.  
  260.     case cSHOWAPPLWIN:
  261.     ShowApplicationWindow();
  262.     break;
  263.  
  264.     case cOPEN:
  265.     Open();
  266.     break;
  267.     
  268.     default:
  269.     if (cmd >= cDEBUGFIRST && cmd <= cDEBUGLAST)
  270.         Debug(cmd-cDEBUGFIRST+1);
  271.     }
  272. }
  273.  
  274. Command *Application::DoMenuCommand(int cmd)
  275. {  
  276.     HandleApplicationCommands(cmd);          
  277.     return gNoChanges;
  278. }
  279.  
  280. void Application::Control(int id, int, void*)
  281.     HandleApplicationCommands(id);
  282. }
  283.  
  284. void Application::Quit()
  285. {
  286.     if (CloseAllDocuments())
  287.     gSystem->ExitControl();
  288. }
  289.  
  290. void Application::Debug(int)
  291. {
  292.     gDebug= (::gDebug= ! ::gDebug);
  293. }
  294.  
  295. void Application::Open()
  296. {
  297.     if (fileDialog == 0)
  298.     fileDialog= MakeFileDialog();
  299.     if (fileDialog->ShowInWindow(eFDRead, applDialog->GetWindow(), this) == cIdOk)
  300.     OpenDocument(fileDialog->FileName());
  301. }
  302.  
  303. void Application::AddDocument(Document *dp)
  304. {
  305.     documents->Add(dp);
  306.     dp->SetApplication(this);
  307. }
  308.  
  309. Document *Application::FindDocument(int id)
  310. {
  311.     Document *dp;
  312.     Iter next(documents);
  313.  
  314.     while (dp= (Document*) next())
  315.     if (dp->UniqueId() == id)
  316.         return dp;
  317.     return 0;
  318. }
  319.  
  320. Document *Application::DoMakeDocuments(const char*)
  321. {
  322.     AbstractMethod("DoMakeDocuments");
  323.     return 0;
  324. }
  325.  
  326. bool Application::CloseAllDocuments()
  327. {
  328.     Document *dp;
  329.     Iter next(documents);
  330.  
  331.     while (dp= (Document*) next()) // try to close all documents
  332.     if (! dp->Close())
  333.         return FALSE;
  334.     return TRUE;
  335. }
  336.  
  337. void Application::OpenDocument(char *name)
  338. {
  339.     Document *dp;
  340.     FType ft(name);
  341.  
  342.     if (!CanOpenDocument(ft.FileType())) {
  343.     ShowAlert(eAlertNote, "cannot handle document @I%s@P (%s)\n", name, ft.Type());
  344.     return;
  345.     }
  346.     dp= DoMakeDocuments(ft.Type()); // let user make his documents
  347.     if (dp) {
  348.     AddDocument(dp);
  349.     dp->OpenWindows();
  350.     dp->Load(name, TRUE, ft.FileType());
  351.     }
  352. }
  353.  
  354. void Application::NewDocument(const char *type)
  355. {
  356.     Document *dp;
  357.  
  358.     dp= DoMakeDocuments(type); // let user make his documents
  359.     if (dp == 0) {
  360.     Error("NewDocument", "DoMakeDocuments returns 0");
  361.     return;
  362.     }
  363.     AddDocument(dp);
  364.     dp->SetName(form("untitled.%d", untitledCnt++));
  365.     dp->OpenWindows();
  366. }
  367.  
  368. bool Application::CanOpenDocument(FileType *ft)
  369. {
  370.     if (strismember(mainDocumentType, cDocTypeUndef, ft->Type(), 0))
  371.     return TRUE;
  372.     if (strcmp(mainDocumentType, cDocTypeAscii) == 0 && ft->IsAscii())
  373.     return TRUE;
  374.     return FALSE;
  375. }
  376.  
  377. int Application::Run()
  378. {
  379.     ApplInit();
  380.     
  381.     applDialog= new ApplDialog(this, gProgname);
  382.     gSystem->AddSignalHandler(new ApplIntHandler);
  383.     gClassManager->SetDynLoadHook(this, (OObjMemberFunc)&Application::DynLoad);
  384.  
  385.     gClipBoard= clipboard= gWindowSystem->MakeClipboard();
  386.     
  387.     OpenApplicationDialog(GetNewDocumentPos());
  388.     
  389.     gSystem->Control();
  390.     
  391.     SafeDelete(clipboard);
  392.     gClipBoard= 0;
  393.  
  394.     applDialog->Close();
  395.     
  396.     return 0;
  397. }
  398.  
  399. void Application::OpenApplicationDialog(Point p)
  400. {
  401.     applDialog->ShowAt(0, p);
  402. }
  403.  
  404. int Application::DynLoad(char *name)
  405. {
  406.     Object *op= gSystem->Load(gProgname, name);
  407.     if (op == 0) {
  408.     Error("DynLoad", "cannot load class");
  409.     return 0;
  410.     }
  411.     return DynLoadHook(op);
  412. }
  413.  
  414. int Application::DynLoadHook(Object*)
  415. {
  416.     return 1;
  417. }
  418.  
  419. VObject *Application::DoCreateDialog() 
  420.     return new BorderItem(
  421.         new Expander(cIdNone, eHor, 5,
  422.             new ActionButton(cNEW,  "new"),
  423.             new ActionButton(cOPEN, "open"),
  424.             new ActionButton(cQUIT, "quit"),
  425.             0
  426.         ),
  427.         Point(5)
  428.         );
  429. }
  430.  
  431. void Application::ShowApplicationWindow()
  432. {
  433.     if (applDialog)
  434.     applDialog->GetWindow()->Open();    
  435. }
  436.  
  437. void Application::InspectorId(char *buf, int sz)
  438. {
  439.     strn0cpy(buf, argv[0], sz);
  440. }
  441.  
  442. void Application::Parts(Collection* col)
  443. {
  444.     EvtHandler::Parts(col);
  445.     col->AddVector(documents, applDialog, 0);
  446. }
  447.  
  448. void Application::UpdateGlobals()
  449. {
  450.     extern IdDictionary *ObjectGetObservers();
  451.     
  452.     gApplication= this;
  453.     gClassManager= ::gClassManager;
  454.     gWindow= ::gWindow;
  455.     gDebug= ::gDebug;
  456.     gBatch= ::gBatch;
  457.     gScreenRect= ::gScreenRect;
  458.     gObservers= ObjectGetObservers();
  459.     gEnviron= environ;
  460. }
  461.  
  462. void Application::DoOnError(int level, char *location, char *msg)
  463. {
  464.     int ignorelevel= GetIgnoreLevel();
  465.     static bool inError= FALSE;
  466.     
  467.     if (level < ignorelevel || inError)
  468.     return;
  469.     inError= TRUE;
  470.     
  471.     char *type= "Warning";
  472.     if (level >= cFatal)
  473.     type= "Fatal";
  474.     else if (level >= cSysError)
  475.     type= "SysError";
  476.     else if (level >= cError)
  477.     type= "Error";
  478.     
  479.     cerr.form("%s: %s in <%s>: %s\n", ProgramName(), type, location, msg);
  480.     if (level >= cError) {
  481.     switch (ShowAlert(eAlertError, "%s: %s\nin @B%s@B: %s", ProgramName(), type, location, msg)) {
  482.     case cIdIgnore:
  483.         break;
  484.         
  485.     case cIdAbort:
  486.         Abort();
  487.         
  488.     case cIdInspect:
  489.         Inspect();
  490.         break;
  491.     }
  492.     }
  493.     inError= FALSE;
  494. }
  495.  
  496.